package com.lovely3x.jobservice.executors.extensions.downloader2.factory;

import android.support.annotation.MainThread;

import com.lovely3x.jobservice.JobService;
import com.lovely3x.jobservice.executors.TaskExecutor;
import com.lovely3x.jobservice.executors.extensions.downloader2.DownloadTask;
import com.lovely3x.jobservice.executors.extensions.downloader2.executor.DownloadTaskExecutor;
import com.lovely3x.jobservice.executors.extensions.downloader2.serializer.DownloadTaskSerializer;
import com.lovely3x.jobservice.factory.ExecutorFactory;
import com.lovely3x.jobservice.serializer.TaskSerializer;
import com.lovely3x.jobservice.task.Progress;
import com.lovely3x.jobservice.task.Task;

import java.util.ArrayList;

/**
 * 下载器工厂
 * Created by lovely3x on 16-2-2.
 */
public class DownloaderFactory implements ExecutorFactory {

    /**
     * 任务执行器的类型
     * 外部调用者通过这个标识来指定是使用Downloader
     */
    public static final String TASK_EXECUTOR_TYPE = "downloader";
    /**
     * 忙碌任务的定义
     */
    private static final int BUSY_TASK_NUM = 3;

    /***
     * 任务执行者列表
     */
    private final ArrayList<DownloadTaskExecutor> DOWNLOAD_TASK_EXECUTORS = new ArrayList<>();

    /**
     * 服务咯
     */
    private JobService mJobService;

    /**
     * 序列化器
     */
    private DownloadTaskSerializer mDownloadSerializer;

    @Override
    public TaskExecutor createExecutor(Task task) {
        if (task == null) return null;
        if (task instanceof DownloadTask && TASK_EXECUTOR_TYPE.equals(task.getTaskType())) {
            DownloadTaskExecutor downloader = new DownloadTaskExecutor();
            DOWNLOAD_TASK_EXECUTORS.add(downloader);
            performOnCreate(downloader);
            return downloader;
        }
        return null;
    }

    @Override
    public TaskSerializer getTaskSerializer() {
        return mDownloadSerializer;
    }

    @Override
    public boolean isBusy() {
        int runningTaskNum = 0;
        for (DownloadTaskExecutor taskExecutor : DOWNLOAD_TASK_EXECUTORS) {
            final Progress progress = taskExecutor.getProgress();
            synchronized (progress) {
                switch (progress.getState()) {
                    case Progress.State.EXECUTING:
                        runningTaskNum++;
                        break;
                }
            }

            if (runningTaskNum > BUSY_TASK_NUM) return true;
        }

        return false;
    }

    @Override
    public boolean handleable(Task task) {
        return task != null && TASK_EXECUTOR_TYPE.equals(task.getTaskType());
    }

    @Override
    public void onCreate(JobService service) {
        this.mJobService = service;
        mDownloadSerializer = new DownloadTaskSerializer();
        mDownloadSerializer.onCreate(mJobService);
    }

    @Override
    public void onDestroy(JobService service) {
        this.mDownloadSerializer.onDestroy();
        for (DownloadTaskExecutor executor : DOWNLOAD_TASK_EXECUTORS) performOnDestroy(executor);
        this.mJobService = null;
    }

    @MainThread
    public void performOnCreate(TaskExecutor executor) {
        if (executor != null && mJobService != null) executor.onCreate(mJobService);
    }

    @MainThread
    public void performOnDestroy(TaskExecutor executor) {
        if (executor != null && mJobService != null) executor.onDestroy();
    }
}
